package xj.toolkit.jmx.model;

import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xj.toolkit.jmx.util.MBeanServerConnectionSource;

public class OperationsContextUnion {
	private static final Logger LOG = LoggerFactory
			.getLogger(OperationsContextUnion.class);
	private final MBeanServerConnectionSource _source;

	public OperationsContextUnion(MBeanServerConnectionSource source) {
		this._source = source;
	}

	public OperationsContext getContextOf(String key, FeaturesDescription desc) {
		ContextUnion union = createOrGetUnion(key);

		OperationsContext ctx = (OperationsContext) union.get(desc);
		if (null != ctx) {
			return ctx;
		}
		MBeanServerConnection mbsc = this._source.getMBeanServerConnection(key);
		if (null == mbsc) {
			LOG.warn(
					"can't get MBeanServerConnection for {}, return null for desc {}",
					key, desc);

			return null;
		}
		ctx = new FeaturesLoader(mbsc).loadOperationsContext(desc);
		if (null == ctx) {
			LOG.warn("can't get OperationsContext for {}/desc {}, return null",
					key, desc);

			return null;
		}
		union.put(desc, ctx);

		return ctx;
	}

	public void invalidContextOf(String key, FeaturesDescription desc) {
		ContextUnion union = getUnion(key);
		if (null != union) {
			union.remove(desc);
		}
	}

	public boolean isContextExist(String key, FeaturesDescription desc) {
		ContextUnion union = getUnion(key);
		if (null != union) {
			return null != union.get(desc);
		}
		return false;
	}

	public ContextUnion getUnion(String key) {
		return (ContextUnion) this._ctxs.get(key);
	}

	public ContextUnion createOrGetUnion(String key) {
		ContextUnion union = (ContextUnion) this._ctxs.get(key);
		if (null == union) {
			union = new ContextUnion();
			this._ctxs.put(key, union);
		}
		return union;
	}

	private final Map<String, ContextUnion> _ctxs = new HashMap();

	private static class ContextUnion extends
			HashMap<FeaturesDescription, OperationsContext> {
		private static final long serialVersionUID = 1L;
	}
}
